/*
 * Create in 2012-11-19 下午3:55:15.
 */
package kit4j.util.lang;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * 对象常用操作工具类。
 * 
 * @author MiniKnife
 * 
 */
public abstract class ObjectUtil {

	/**
	 * 验证给定的值是否为null并返回验证后期望的值。
	 * 
	 * @param value
	 *            要验证的值
	 * @param defaultValue
	 *            默认值
	 * @return 如果给定的对象不为null，则直接返回该对象，否则返回默认值。
	 */
	public static <T> T checkNull(T value, T defaultValue) {
		if (value != null) {
			return value;
		} else {
			return defaultValue;
		}
	}

	/**
	 * 验证给定的两个对象是否相等。如果两个对象都为null，则认为两个对象相等，否则调用给定对象的equals(Object)方法进行判断。
	 * 
	 * @param v1
	 *            要比较的对象
	 * @param v2
	 *            要比较的对象
	 * @return 如果两个对象相等，则返回true，否则返回false。
	 */
	public static boolean equals(Object v1, Object v2) {
		return v1 == null ? v2 == null : v1.equals(v2);
	}

	/**
	 * 将给定的对象转换为序列化字节数组。
	 * 
	 * @param obj
	 *            要转换的对象
	 * @return 对象的序列化字节数组。
	 * @throws NullPointerException
	 *             如果给定的对象为null。
	 */
	public static byte[] toByteArray(Serializable obj) {
		ByteArrayOutputStream byteOut = new ByteArrayOutputStream();

		try {
			ObjectOutputStream objOut = new ObjectOutputStream(byteOut);
			objOut.writeObject(obj);
		} catch (IOException e) {
			e.printStackTrace();
		}

		return byteOut.toByteArray();
	}

	/**
	 * 从给定的对象序列化字节数组中读取回对象。
	 * 
	 * @param bts
	 *            对象的序列化字节数组
	 * @param clazz
	 *            对象类型
	 * @return 从对象的序列化字节数组中读取到的对象。
	 * @throws ClassNotFoundException
	 *             找不到序列化对象的类。
	 * @throws ClassCastException
	 *             读取到的对象无法转型到给定的类型。
	 * @throws NullPointerException
	 *             如果给定的对象字节数组为空或对象类型为null。
	 */
	public static <T> T toObject(byte[] bts, Class<T> clazz) throws ClassNotFoundException, ClassCastException {
		ByteArrayInputStream byteIn = new ByteArrayInputStream(bts);
		try {
			ObjectInputStream objIn = new ObjectInputStream(byteIn);
			Object obj = objIn.readObject();

			return clazz.cast(obj);
		} catch (IOException e) {
			e.printStackTrace();

			return null;
		}
	}
}
